package com.apigen.platform.service.impl;

import com.apigen.platform.dto.CaptchaResponse;
import com.apigen.platform.service.ICaptchaService;
import com.apigen.platform.util.CaptchaUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 验证码服务实现类
 *
 * @author API Generator Platform
 * @since 2025-09-24
 */
@Slf4j
@Service
public class CaptchaServiceImpl implements ICaptchaService {

    @Autowired(required = false)
    private RedisTemplate<String, Object> redisTemplate;

    private static final String CAPTCHA_PREFIX = "captcha:";
    private static final int CAPTCHA_EXPIRE_TIME = 300; // 5分钟过期

    @Override
    public CaptchaResponse generateCaptcha() {
        try {
            // 1. 生成验证码
            CaptchaUtil.CaptchaResult captchaResult = CaptchaUtil.generateCaptcha();
            
            // 2. 生成唯一标识
            String captchaId = generateCaptchaId();
            
            // 3. 缓存验证码
            cacheCaptcha(captchaId, captchaResult.getCode());
            
            // 4. 构建响应
            long expireTime = System.currentTimeMillis() + (CAPTCHA_EXPIRE_TIME * 1000L);
            
            return new CaptchaResponse(
                captchaId,
                captchaResult.getImageBase64(),
                expireTime,
                CAPTCHA_EXPIRE_TIME
            );
            
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            throw new RuntimeException("生成验证码失败", e);
        }
    }

    @Override
    public boolean validateCaptcha(String captchaId, String captchaCode) {
        if (!StringUtils.hasText(captchaId) || !StringUtils.hasText(captchaCode)) {
            return false;
        }

        try {
            // 1. 从缓存获取验证码
            String cachedCode = getCachedCaptcha(captchaId);
            if (cachedCode == null) {
                log.warn("验证码不存在或已过期: {}", captchaId);
                return false;
            }

            // 2. 验证码验证
            boolean isValid = CaptchaUtil.validateCaptcha(captchaCode, cachedCode);
            
            // 3. 验证成功后删除缓存（一次性验证码）
            if (isValid) {
                deleteCachedCaptcha(captchaId);
            }
            
            return isValid;
            
        } catch (Exception e) {
            log.error("验证验证码失败", e);
            return false;
        }
    }

    @Override
    public CaptchaResponse refreshCaptcha(String captchaId) {
        try {
            // 删除旧的验证码
            if (StringUtils.hasText(captchaId)) {
                deleteCachedCaptcha(captchaId);
            }
            
            // 生成新的验证码
            return generateCaptcha();
            
        } catch (Exception e) {
            log.error("刷新验证码失败", e);
            throw new RuntimeException("刷新验证码失败", e);
        }
    }

    @Override
    public void cleanExpiredCaptcha() {
        // Redis会自动清理过期的key，这里可以添加额外的清理逻辑
        log.info("清理过期验证码任务执行");
    }

    /**
     * 生成验证码ID
     */
    private String generateCaptchaId() {
        return "captcha_" + UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 缓存验证码
     */
    private void cacheCaptcha(String captchaId, String captchaCode) {
        String key = CAPTCHA_PREFIX + captchaId;
        
        if (redisTemplate != null) {
            // 使用Redis缓存
            redisTemplate.opsForValue().set(key, captchaCode, CAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
            log.debug("验证码已缓存到Redis: {}", captchaId);
        } else {
            // 如果没有Redis，使用内存缓存（简单实现）
            // 注意：在生产环境中建议使用Redis或其他分布式缓存
            log.warn("Redis未配置，验证码将存储在内存中（不推荐用于生产环境）");
            // 这里可以实现一个简单的内存缓存
        }
    }

    /**
     * 获取缓存的验证码
     */
    private String getCachedCaptcha(String captchaId) {
        String key = CAPTCHA_PREFIX + captchaId;
        
        if (redisTemplate != null) {
            Object cachedCode = redisTemplate.opsForValue().get(key);
            return cachedCode != null ? cachedCode.toString() : null;
        } else {
            // 内存缓存实现
            return null;
        }
    }

    /**
     * 删除缓存的验证码
     */
    private void deleteCachedCaptcha(String captchaId) {
        String key = CAPTCHA_PREFIX + captchaId;
        
        if (redisTemplate != null) {
            redisTemplate.delete(key);
            log.debug("验证码已从缓存中删除: {}", captchaId);
        }
    }
}
